`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2021/09/18 19:19:56
// Design Name: 
// Module Name: e203_subsys_nice_multicore
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module e203_subsys_nice_icb_bridge(
 // System	
    input                         nice_clk            ,
    input                         nice_rst_n	      ,
    output                        nice_active	      ,
    output                        nice_mem_holdup	  ,
//    output                        nice_rsp_err_irq	  ,
    // Control cmd_req
    input                         nice_req_valid       ,
    output                        nice_req_ready       ,
    input  [`E203_XLEN-1:0]       nice_req_inst        ,
    input  [`E203_XLEN-1:0]       nice_req_rs1         ,
    input  [`E203_XLEN-1:0]       nice_req_rs2         ,
    // Control cmd_rsp	
    output                        nice_rsp_valid       ,
    input                         nice_rsp_ready       ,
    output [`E203_XLEN-1:0]       nice_rsp_rdat        ,
    output                        nice_rsp_err    	  ,
    // Memory lsu_req	
    output                        nice_icb_cmd_valid   ,
    input                         nice_icb_cmd_ready   ,
    output [`E203_ADDR_SIZE-1:0]  nice_icb_cmd_addr    ,
    output                        nice_icb_cmd_read    ,
    output [`E203_XLEN-1:0]       nice_icb_cmd_wdata   ,
//    output [`E203_XLEN_MW-1:0]     nice_icb_cmd_wmask   ,  // 
    output [1:0]                  nice_icb_cmd_size    ,
    // Memory lsu_rsp	
    input                         nice_icb_rsp_valid   ,
    output                        nice_icb_rsp_ready   ,
    input  [`E203_XLEN-1:0]       nice_icb_rsp_rdata   ,
    input                         nice_icb_rsp_err,
    // adc enframe block interface
    input                         u_mrt_wen           ,
    input     [24*2-1: 0]         u_mrt_cfg_data      ,
    input                         u_mrt_cfg_last      ,
    //interrupt interface
    output                        u_mrt_finish        ,
    //design for test
    input                         t_nice_core_isolate ,
    input  [12-1:0]               t_nice_core_cfg     ,
    output [48-1:0]               t_nice_core_res
    );
    // test input
    wire  [3-1:0]                t_nice_cmd_short    ;
    wire  [4-1:0]                t_nice_rs1_short    ;
    wire  [4-1:0]                t_nice_rs2_short    ;
    wire                         t_nice_cmd_valid    ;
    //test output
    wire [`E203_XLEN-1:0]       t_nice_rsp_rdat     ;
    wire                        t_nice_rsp_valid    ;
    wire [8-1:0]                t_nice_icb_addr_short;
    wire                        t_nice_icb_cmd_valid;    
    wire                        t_nice_icb_read     ;
    wire [4-1:0]                t_nice_icb_wdata_short;
    wire                        t_nice_mem_holdup    ;
    
    wire [`E203_XLEN-1:0]       nice_rsp_rdat_m     ;
    wire                        nice_rsp_valid_m    ;
    wire [`E203_XLEN-1:0]       nice_icb_cmd_addr_m ;
    wire                        nice_icb_cmd_valid_m;    
    wire                        nice_icb_cmd_read_m ;
    wire [`E203_XLEN-1:0]       nice_icb_cmd_wdata_m;
    wire                        nice_mem_holdup_m   ;
    
    assign t_nice_rsp_rdat = nice_rsp_rdat_m;
    assign t_nice_rsp_valid = nice_rsp_valid_m;
    assign t_nice_icb_addr_short = {nice_icb_cmd_addr_m[31:31-4],nice_icb_cmd_addr_m[3:0]};
    assign t_nice_icb_cmd_valid = nice_icb_cmd_valid_m;
    assign t_nice_icb_read = nice_icb_cmd_read_m;
    assign t_nice_icb_wdata_short = nice_icb_cmd_wdata_m[3:0];
    assign t_nice_mem_holdup = nice_mem_holdup_m;
    
    
    assign t_nice_core_res = t_nice_core_isolate ? {t_nice_rsp_rdat,t_nice_rsp_valid,t_nice_icb_addr_short,t_nice_icb_cmd_valid,t_nice_icb_read,t_nice_icb_wdata_short,t_nice_mem_holdup}
                                                 : 48'd0;
    assign t_nice_cmd_valid = t_nice_core_cfg[11];
    assign t_nice_cmd_short = t_nice_core_cfg[10:8];
    assign t_nice_rs1_short = t_nice_core_cfg[7:4];
    assign t_nice_rs2_short = t_nice_core_cfg[3:0];
    
    reg [32-1:0] t_nice_cmd_full;
    wire [32-1:0] t_nice_rs1_full;
    wire [32-1:0] t_nice_rs2_full;
    always@(*)begin
        case(t_nice_cmd_short)
            4'd0:t_nice_cmd_full = 32'b0000100_00000_00000_111_00000_1111011;      //NODEF
            4'd1:t_nice_cmd_full = 32'b0000001_00000_00000_110_00000_1111011;      //MRT_RDSTAT
            4'd2:t_nice_cmd_full = 32'b0000010_00000_00000_100_00000_1111011;      //MRT_START
            4'd3:t_nice_cmd_full = 32'b0000101_00000_00000_110_00000_1111011;      //PRG_RDSTAT
            4'd4:t_nice_cmd_full = 32'b0000110_00000_00000_111_00000_1111011;      //PRG_START
            default:t_nice_cmd_full = 32'b0;
        endcase
    end
    
    assign t_nice_rs1_full = {t_nice_rs1_short[3],25'd0,t_nice_rs1_short[2],3'd0,t_nice_rs1_short[1:0]};
    assign t_nice_rs2_full = {t_nice_rs2_short,28'd0};
    
    // output
    wire nice_mrt_req_ready, nice_prg_req_ready;
    wire nice_mrt_rsp_valid, nice_prg_rsp_valid;
    assign nice_req_ready = t_nice_core_isolate ? 1'b0 : nice_mrt_req_ready & nice_prg_req_ready;
    assign nice_rsp_valid = t_nice_core_isolate ? 1'b0 : nice_rsp_valid_m;
    assign nice_rsp_valid_m = nice_mrt_rsp_valid | nice_prg_rsp_valid;
    
    wire [`E203_XLEN-1:0] nice_mrt_rsp_rdat, nice_prg_rsp_rdat;
    assign nice_rsp_rdat = t_nice_core_isolate ? 32'd0 : nice_rsp_rdat_m;
    assign nice_rsp_rdat_m = nice_mrt_rsp_rdat | nice_prg_rsp_rdat;
    
    wire nice_mrt_rsp_err, nice_prg_rsp_err;
    assign nice_rsp_err = t_nice_core_isolate ? 1'b0 : nice_mrt_rsp_err | nice_prg_rsp_err;
    
    wire nice_mrt_mem_holdup, nice_prg_mem_holdup;
    assign nice_mem_holdup = t_nice_core_isolate ? 1'b0 : nice_mem_holdup_m;
    assign nice_mem_holdup_m = nice_mrt_mem_holdup | nice_prg_mem_holdup;

    wire                        nice_mrt_icb_cmd_valid   ,nice_prg_icb_cmd_valid;
    wire                        nice_mrt_icb_cmd_ready   ,nice_prg_icb_cmd_ready;
    wire [`E203_ADDR_SIZE-1:0]  nice_mrt_icb_cmd_addr    ,nice_prg_icb_cmd_addr;
    wire                        nice_prg_icb_cmd_read    ,nice_mrt_icb_cmd_read;
    wire [`E203_XLEN-1:0]       nice_mrt_icb_cmd_wdata   ,nice_prg_icb_cmd_wdata;
    wire [1:0]                  nice_mrt_icb_cmd_size    ,nice_prg_icb_cmd_size;
    wire                        nice_mrt_icb_rsp_valid   ,nice_prg_icb_rsp_valid;
    wire                        nice_mrt_icb_rsp_ready   ,nice_prg_icb_rsp_ready;
    wire  [`E203_XLEN-1:0]      nice_mrt_icb_rsp_rdata   ,nice_prg_icb_rsp_rdata;
    wire                        nice_mrt_icb_rsp_err     ,nice_prg_icb_rsp_err;
    wire                        nice_com_req_valid       ;
    wire  [`E203_XLEN-1:0]      nice_com_req_inst        ;
    wire  [`E203_XLEN-1:0]      nice_com_req_rs1         ;
    wire  [`E203_XLEN-1:0]      nice_com_req_rs2         ;
    wire                        nice_com_rsp_ready       ;
    // output
    assign nice_icb_cmd_valid = t_nice_core_isolate ? 1'b0                   : nice_icb_cmd_valid_m;
    assign nice_icb_cmd_valid_m = nice_mrt_mem_holdup ? nice_mrt_icb_cmd_valid : 
                                nice_prg_mem_holdup ? nice_prg_icb_cmd_valid :
                                                      1'b0;
    assign nice_icb_cmd_addr  = t_nice_core_isolate ? {`E203_ADDR_SIZE{1'b0}}: nice_icb_cmd_addr_m;
    assign nice_icb_cmd_addr_m  = nice_mrt_mem_holdup ? nice_mrt_icb_cmd_addr  : 
                                nice_prg_mem_holdup ? nice_prg_icb_cmd_addr  :
                                                      {`E203_ADDR_SIZE{1'b0}};
    assign nice_icb_cmd_read  = t_nice_core_isolate ? 1'b1 : nice_icb_cmd_read_m;
    assign nice_icb_cmd_read_m = nice_mrt_mem_holdup ? nice_mrt_icb_cmd_read  : 
                                nice_prg_mem_holdup ? nice_prg_icb_cmd_read  :
                                                      1'b1;
    assign nice_icb_cmd_wdata = t_nice_core_isolate ? {`E203_XLEN{1'b0}} : nice_icb_cmd_wdata_m;
    assign nice_icb_cmd_wdata_m = nice_mrt_mem_holdup ? nice_mrt_icb_cmd_wdata : 
                                nice_prg_mem_holdup ? nice_prg_icb_cmd_wdata :
                                                      {`E203_XLEN{1'b0}};
    assign nice_icb_cmd_size  = t_nice_core_isolate ? 2'b0 : nice_mrt_icb_cmd_size;
    assign nice_icb_rsp_ready = t_nice_core_isolate ? 1'b0                   :
                                nice_mrt_mem_holdup ? nice_mrt_icb_rsp_ready : 
                                nice_prg_mem_holdup ? nice_prg_icb_rsp_ready :
                                                      1'b1;
    
    
    // input
    assign nice_mrt_icb_cmd_ready = t_nice_core_isolate ? 1'b0 : nice_icb_cmd_ready & ~nice_prg_mem_holdup;
    assign nice_mrt_icb_rsp_valid = t_nice_core_isolate ? 1'b0 : nice_mrt_mem_holdup & nice_icb_rsp_valid;
    assign nice_mrt_icb_rsp_rdata = t_nice_core_isolate ? {`E203_XLEN{1'b0}} : {`E203_XLEN{nice_mrt_mem_holdup}} & nice_icb_rsp_rdata;
    assign nice_mrt_icb_rsp_err   = t_nice_core_isolate ? 1'b0 : nice_mrt_mem_holdup & nice_icb_rsp_err;
    
    assign nice_prg_icb_cmd_ready = t_nice_core_isolate ? ~nice_mrt_mem_holdup : nice_icb_cmd_ready & ~nice_mrt_mem_holdup;
    assign nice_prg_icb_rsp_valid = t_nice_core_isolate ? nice_prg_mem_holdup : nice_prg_mem_holdup & nice_icb_rsp_valid;
    assign nice_prg_icb_rsp_rdata = t_nice_core_isolate ? `E203_XLEN'hAAAA : {`E203_XLEN{nice_prg_mem_holdup}} & nice_icb_rsp_rdata;
    assign nice_prg_icb_rsp_err   = t_nice_core_isolate ? 1'b0 : nice_prg_mem_holdup & nice_icb_rsp_err;
    
    // common port
    assign nice_com_req_valid = t_nice_core_isolate ? t_nice_cmd_valid : nice_req_valid;
    assign nice_com_req_inst = t_nice_core_isolate ? t_nice_cmd_full : nice_req_inst;
    assign nice_com_req_rs1 = t_nice_core_isolate ? t_nice_rs1_full : nice_req_rs1;
    assign nice_com_req_rs2 = t_nice_core_isolate ? t_nice_rs2_full : nice_req_rs2;
    assign nice_com_rsp_ready = t_nice_core_isolate ? 1'b1 : nice_rsp_ready;
    
    e203_subsys_nice_mrt_core u_e203_nice_mrt_core  (
    
        .nice_clk             (nice_clk),
        .nice_rst_n	          (nice_rst_n),
        .nice_active	      (),
        .nice_mem_holdup	  (nice_mrt_mem_holdup),
        
        .nice_req_valid       (nice_com_req_valid),
        .nice_req_ready       (nice_mrt_req_ready),
        .nice_req_inst        (nice_com_req_inst),
        .nice_req_rs1         (nice_com_req_rs1),
        .nice_req_rs2         (nice_com_req_rs2),
        
        .nice_rsp_valid       (nice_mrt_rsp_valid),
        .nice_rsp_ready       (nice_com_rsp_ready),
        .nice_rsp_rdat        (nice_mrt_rsp_rdat),
        .nice_rsp_err    	  (nice_mrt_rsp_err),
        
        .nice_icb_cmd_valid   (nice_mrt_icb_cmd_valid),
        .nice_icb_cmd_ready   (nice_mrt_icb_cmd_ready),
        .nice_icb_cmd_addr    (nice_mrt_icb_cmd_addr),
        .nice_icb_cmd_read    (nice_mrt_icb_cmd_read),
        .nice_icb_cmd_wdata   (nice_mrt_icb_cmd_wdata),
        .nice_icb_cmd_size    (nice_mrt_icb_cmd_size),
        
        .nice_icb_rsp_valid   (nice_mrt_icb_rsp_valid),
        .nice_icb_rsp_ready   (nice_mrt_icb_rsp_ready),
        .nice_icb_rsp_rdata   (nice_mrt_icb_rsp_rdata),
        .nice_icb_rsp_err     (nice_mrt_icb_rsp_err),
            // adc enframe block interface
        .u_mrt_wen            (u_mrt_wen),
        .u_mrt_cfg_data       (u_mrt_cfg_data),
        .u_mrt_cfg_last       (u_mrt_cfg_last),
        //interrupt interface
        .u_mrt_finish         (u_mrt_finish)

   );
   
   e203_subsys_nice_prg_core u_e203_nice_prg_core  (
    
        .nice_clk             (nice_clk),
        .nice_rst_n	          (nice_rst_n),
        .nice_active	      (),
        .nice_mem_holdup	  (nice_prg_mem_holdup),
        
        .nice_req_valid       (nice_com_req_valid),
        .nice_req_ready       (nice_prg_req_ready),
        .nice_req_inst        (nice_com_req_inst),
        .nice_req_rs1         (nice_com_req_rs1),
        .nice_req_rs2         (nice_com_req_rs2),
        
        .nice_rsp_valid       (nice_prg_rsp_valid),
        .nice_rsp_ready       (nice_com_rsp_ready),
        .nice_rsp_rdat        (nice_prg_rsp_rdat),
        .nice_rsp_err    	  (nice_prg_rsp_err),
        
        .nice_icb_cmd_valid   (nice_prg_icb_cmd_valid),
        .nice_icb_cmd_ready   (nice_prg_icb_cmd_ready),
        .nice_icb_cmd_addr    (nice_prg_icb_cmd_addr),
        .nice_icb_cmd_read    (nice_prg_icb_cmd_read),
        .nice_icb_cmd_wdata   (nice_prg_icb_cmd_wdata),
        .nice_icb_cmd_size    (nice_prg_icb_cmd_size),
        
        .nice_icb_rsp_valid   (nice_prg_icb_rsp_valid),
        .nice_icb_rsp_ready   (nice_prg_icb_rsp_ready),
        .nice_icb_rsp_rdata   (nice_prg_icb_rsp_rdata),
        .nice_icb_rsp_err     (nice_prg_icb_rsp_err)	

   );
    
endmodule
